import re
import time
from appium.webdriver.common.appiumby import AppiumBy
from appium.webdriver.webdriver import WebDriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions import interaction
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.pointer_input import PointerInput

from cash_pos.constants.common_sequence import ShiftTurnoverSettlement, SWITCH_ENV
from cash_pos.function.common_function import CommonFunction


class DailySettlementPage(object):

    def __init__(self, client):
        self.client = client
        self.driver: WebDriver = client.driver
        self.width = client.width
        self.height = client.height

    """
    SubPage Function
    """

    def start_class(self):
        """
        开班（兼容性输入数值）
        """
        content = self.driver.find_element(AppiumBy.XPATH,
                                           f'//android.widget.TextView[@resource-id="{SWITCH_ENV}:id/tv_title"]').text
        assert content in ["开班"]
        # 钱箱余额
        balance_account_desc = self.driver.find_element(AppiumBy.XPATH,
                                                        f'//android.widget.TextView[@resource-id="{SWITCH_ENV}:id/tv_balance"]').text
        balance_account_list = list(str(balance_account_desc.split(": ")[1].strip()))
        element = self.driver.find_element(AppiumBy.XPATH,
                                           f'//android.view.View[@resource-id="{SWITCH_ENV}:id/keyboard"]')
        width, height = element.size["width"], element.size["height"]
        from_element_location = re.match(r"\[(\d+,\d+)\]\[(\d+,\d+)\]", element.get_attribute("bounds")).group(1).split(',')
        from_x, from_y = int(from_element_location[0]), int(from_element_location[1])
        unit_x, unit_y = width / 3, height / 4
        for num in balance_account_list:
            if num.isdigit() and int(num) != 0:
                x = from_x + ((int(num) % 3 if int(num) % 3 != 0 else 3) - 1) * unit_x + 10
                step = (int(num)) // 3 if (int(num)) % 3 != 0 else (int(num)) // 3 - 1
                y = from_y + step * unit_y + 10
            elif num.isdigit() and int(num) == 0:
                x = from_x + unit_x + 10
                y = from_y + 3 * unit_y + 10
            else:
                x = from_x + 10
                y = from_y + 3 * unit_y + 10
            actions = ActionChains(self.driver)
            actions.w3c_actions = ActionBuilder(self.driver, mouse=PointerInput(interaction.POINTER_TOUCH, "touch"))
            # 计算X,Y值
            actions.w3c_actions.pointer_action.move_to_location(x, y)
            actions.w3c_actions.pointer_action.pointer_down()
            actions.w3c_actions.pointer_action.pause(0.1)
            actions.w3c_actions.pointer_action.release()
            actions.perform()

    """日结详情页"""

    def turnover_detail_cashbox(self):
        """
        交班详情（打开钱箱）
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/open_cash_box').click()
        return self

    def turnover_detail_over_and_settlement(self):
        """
        交班详情（交班并日结）
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/confirm_handover').click()
        return self

    """确认交班页"""

    def last_page(self):
        """
        返回
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_title').click()
        return self

    def confirm_turnover_page_print_turnover(self):
        """
        打印交班单
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/cb_print').click()
        return self

    def confirm_turnover_page_turnover_and_settlement(self):
        """
        交班并日结
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_handover_and_daily_closing').click()
        return self

    def confirm_turnover_page_turnover_and_back(self):
        """
        交班并退出
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_confirm').click()
        return self

    def confirm_turnover_page_cancel(self):
        """
        退出
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/iv_close').click()
        return self

    """确认日结页"""

    def confirm_settlement_page_no_print(self):
        """
        确认日结页不打印直接日结
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_cancel').click()
        return self

    def confirm_settlement_page_print(self):
        """
        确认日结页且打印并日结
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_confirm').click()
        return self

    """补日结页"""

    """日结详情页"""

    def daily_record_detail_page_cashbox(self):
        """
        日结详情页打开钱箱
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/open_cash_box').click()
        return self

    def daily_record_detail_page_confirm_settlement(self):
        """
        日结详情页确认日结
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/confirm_handover').click()
        return self

    """
    Service Function
    """

    def time_sleep(self, time_num: int):
        """
        睡眠时间
        Params:
        -time:睡眠时间
        """
        time.sleep(time_num)
        return self

    def screen_shoot(self, filename, path):
        """
        屏幕截图
        Params:
        -filename:文件名称
        -path:路径
        """
        CommonFunction(self.driver).screen_shoot(filename=filename, path=path)
        return self

    def turn_over_class(self, person_name: str):
        """
        交班
        Params:
        -person_name:开班人
        """
        turnover_container = self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/rv_handover_shift')
        turnover_elements = turnover_container.find_elements(AppiumBy.XPATH, f'./*/*')
        for record in turnover_elements:
            name = record.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_cashier_value').text
            if person_name.strip() == name.strip():
                class_tag = record.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_tag').text
                if class_tag.strip() in ['未交班']:
                    record.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_detail').click()
                    break
        return self

    """
    Button Function
    """

    def switch_turnover_daily_settlement(self, switch_tag: str):
        """
        切换交接班日结
        Params:
        -switch_tag:转化标志
        """
        if switch_tag == ShiftTurnoverSettlement.settlement.value:
            self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_daily_settlement').click()
        if switch_tag == ShiftTurnoverSettlement.turnover.value:
            self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_end_working').click()
        return self

    def turnover_record(self):
        """
        交班记录
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_handover_record').click()
        return self

    def turnover_detail(self, start_class_name):
        """
        交班详情
        Params:
        -start_class_name:开班人
        Note: 在这里的交班详情中默认只是查看第一个，根据开班人来查找，因为匹配具体的时间+开班人逻辑较为复杂
        """
        records = self.driver.find_elements(AppiumBy.XPATH, f'//androidx.recyclerview.widget.RecyclerView[@resource-id="{SWITCH_ENV}:id/rv_handover_shift"]/android.view.ViewGroup')
        for record in records:
            start_person_name = record.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_cashier_value').text
            if start_person_name == start_class_name:
                record.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_detail').click()
                break
        return self

    def action_start_class(self):
        """
        开班
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_open_class').click()
        return self

    def daily_record(self):
        """
        当天日结
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_day_checkout').click()
        return self

    def supply_record(self):
        """
        补日结
        """
        self.driver.find_element(AppiumBy.ID, f'{SWITCH_ENV}:id/tv_add_day_checkout').click()
        return self
